package net.phoenix.repository.value;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Calendar;

import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.ValueFormatException;

import net.phoenix.repository.InputStreamBinary;

/**
 * 
 * Jigsaw server
 * 
 * @author <a href="shamphone@gmail.com">Li XiongFeng</a>
 * @date 2012-1-3
 * @version 1.0.0
 */
public class BasicValueFactory implements ValueFactory {
	
	public BasicValueFactory() {
	}

	/**
	 * 
	 * @param value
	 *            值
	 * @param type
	 *            类型
	 * @throws ValueFormatException
	 * @return Value
	 */
	@Override
	public Value createValue(String value, int type) throws ValueFormatException {
		Value ivalue;
		switch (type) {
		case PropertyType.BINARY:
			ivalue = new BinaryValue(value);
			break;
		case PropertyType.BOOLEAN:
			ivalue = new BooleanValue(value);
			break;
		case PropertyType.DATE:
			ivalue = new DateValue(value);
			break;
		case PropertyType.DOUBLE:
			ivalue = new DoubleValue(value);
			break;
		case PropertyType.LONG:
			ivalue = new LongValue(value);
			break;
		case PropertyType.PATH:
			ivalue = new PathValue(value);
			break;
		case PropertyType.REFERENCE:
			ivalue = new ReferenceValue(value);
			break;
		default:
			ivalue = new StringValue(value);
			break;
		}

		return ivalue;

	}

	/**
	 * 
	 * @param value
	 *            an <code>InputStream</code>
	 * @return a <code>Value</code> of {@link PropertyType#BINARY}
	 */
	@Override
	public Value createValue(InputStream value) {
		BinaryValue bvalue = new BinaryValue(value);
		return bvalue;
	}

	/**
	 * 创建一个字符型的值对象 with the specified <code>value</code>.
	 * 
	 * @param value
	 *            a <code>String</code>
	 * @return a <code>Value</code> of {@link PropertyType#STRING}
	 */
	@Override
	public Value createValue(String value) {
		StringValue svalue = new StringValue(value);
		return svalue;
	}

	/**
	 * 
	 * @param value
	 *            a <code>long</code>
	 * @return a <code>Value</code> of {@link PropertyType#LONG}
	 */
	@Override
	public Value createValue(long value) {
		LongValue lvalue = new LongValue(value);
		return lvalue;
	}

	/**
	 * 
	 * @param value
	 *            a <code>Calendar</code>
	 * @return a <code>Value</code> of {@link PropertyType#DATE}
	 */
	@Override
	public Value createValue(Calendar value) {
		DateValue dvalue = new DateValue(value);
		return dvalue;
	}

	/**
	 * @throws RepositoryException
	 *             if the specified <code>Node</code> is not referencable, the
	 *             current <code>Session</code> is no longer active, or another
	 *             error occurs.
	 * 
	 * @param value
	 *            a <code>Node</code>
	 * @return a <code>Value</code> of {@link PropertyType#REFERENCE}
	 * @throws ValueFormatException
	 */
	@Override
	public Value createValue(Node value) throws ValueFormatException {
		ReferenceValue rvalue = new ReferenceValue(value);
		return rvalue;
	}

	/**
	 * 
	 * @param value
	 *            a <code>boolean</code>
	 * @return a <code>Value</code> of {@link PropertyType#BOOLEAN}
	 */
	@Override
	public Value createValue(boolean value) {
		BooleanValue bvalue = new BooleanValue(value);
		return bvalue;
	}

	/**
	 * Returns a <code>Value</code> object of {@link PropertyType#DOUBLE} with
	 * the specified <code>value</code>.
	 * 
	 * @param value
	 *            a <code>double</code>
	 * @return a <code>Value</code> of {@link PropertyType#DOUBLE}
	 */
	@Override
	public Value createValue(double value) {
		DoubleValue dvalue = new DoubleValue(value);
		return dvalue;
	}

	@Override
	public Value createValue(BigDecimal value) {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.jcr.ValueFactory#createValue(javax.jcr.Binary)
	 */
	@Override
	public Value createValue(Binary value) {
		BinaryValue bvalue = new BinaryValue(value);
		return bvalue;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.jcr.ValueFactory#createValue(javax.jcr.Node, boolean)
	 */
	@Override
	public Value createValue(Node value, boolean weak) throws RepositoryException {
		return this.createValue(value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.jcr.ValueFactory#createBinary(java.io.InputStream)
	 */
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.jcr.ValueFactory#createBinary(java.io.InputStream)
	 */
	@Override
	public Binary createBinary(InputStream stream) throws RepositoryException {
		return new InputStreamBinary(stream);
	}

//	public Value createValue(Object value, int type) throws RepositoryException {
//		InternalValue ivalue;
//		switch (type) {
//		case PropertyType.BINARY:
//			ivalue = new BinaryValue();
//			break;
//		case PropertyType.BOOLEAN:
//			ivalue = new BooleanValue();
//			break;
//		case PropertyType.DATE:
//			ivalue = new DateValue();
//			break;
//		case PropertyType.DOUBLE:
//			ivalue = new DoubleValue();
//
//			break;
//		case PropertyType.LONG:
//			ivalue = new LongValue();
//			break;
//		case PropertyType.PATH:
//			ivalue = new PathValue();
//			break;
//		case PropertyType.REFERENCE:
//			ivalue = new ReferenceValue();
//			break;
//		// case PropertyType.TEXT:
//		// ivalue = new TextValue();
//		// break;
//		default:
//			ivalue = new StringValue();
//			break;
//		}
//		if (value != null) {
//			if (value instanceof String)
//				ivalue.setValue((String) value);
//			else if (value instanceof Integer)
//				ivalue.setValue(((Integer) value).longValue());
//			else if (value instanceof Long)
//				ivalue.setValue(((Long) value).longValue());
//			else if (value instanceof Double)
//				ivalue.setValue(((Double) value).doubleValue());
//			else if (value instanceof Date)
//				ivalue.setValue(((Date) value).getTime());
//			else if (value instanceof Calendar)
//				ivalue.setValue((Calendar) value);
//			else if (value instanceof Node)
//				ivalue.setValue((Node) value);
//			else if (value instanceof Boolean)
//				ivalue.setValue(((Boolean) value).booleanValue());
//			else if (value instanceof Float)
//				ivalue.setValue(((Float) value).doubleValue());
//			else if (value instanceof Binary)
//				ivalue.setValue((Binary) value);
//			else if (value instanceof InputStream)
//				ivalue.setValue(new InputStreamBinary((InputStream) value));
//			else
//				throw new ValueFormatException("Unable to convert data type.");
//		}
//		return ivalue;
//
//	}

}
